package com.rzl.expense.common.utils;


import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 	DateTime
 * @description  对Calendar的封装,以便于使用
 * @author
 * @version  V1.0
 */
public class DateTime implements Serializable {

	/** 用一句话描述这个变量表示什么 */
	private static final long serialVersionUID = 1L;

	/**
	 *
	 * yyyy-MM-dd HH:mm:ss 格式
	 *
	 */
	public static final String DEFAULT_DATE_TIME_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss";

	/**
	 *
	 * yyyy-MM-dd HH:mm 格式
	 *
	 */
	public static final String DEFAULT_DATE_TIME_HHmm_FORMAT_PATTERN = "yyyy-MM-dd HH:mm";

	/**
	 *
	 * yyyy-MM-dd HH 格式
	 *
	 */

	public static final String DEFAULT_DATE_TIME_HH_FORMAT_PATTERN = "yyyy-MM-dd HH";

	/**
	 *
	 * yyyy-MM-dd 格式
	 *
	 */

	public static final String DEFAULT_DATE_FORMAT_PATTERN = "yyyy-MM-dd";

	/**
	 *
	 * HH:mm:ss 格式
	 *
	 */

	public static final String DEFAULT_TIME_FORMAT_PATTERN = "HH:mm:ss";

	/**
	 *
	 * HH:mm 格式
	 *
	 */

	public static final String DEFAULT_TIME_HHmm_FORMAT_PATTERN = "HH:mm";

	/**
	 *
	 *	 年
	 * 	可以通过DateTime.now().get(DateTime.YEAR_FIELD)来获取当前时间的年
	 *
	 */

	public static final int YEAR_FIELD = Calendar.YEAR;

	/**
	 *
	 * 	月
	 * 	可以通过DateTime.now().get(DateTime.MONTH_FIELD)来获取当前时间的月
	 *
	 */

	public static final int MONTH_FIELD = Calendar.MONTH;

	/**
	 *
	 * 	日
	 * 	可以通过DateTime.now().get(DateTime.DAY_FIELD)来获取当前时间的日
	 *
	 */

	public static final int DAY_FIELD = Calendar.DATE;

	/**
	 *
	 * 	小时
	 *	 可以通过DateTime.now().get(DateTime.HOUR_FIELD)来获取当前时间的小时
	 *
	 */

	public static final int HOUR_FIELD = Calendar.HOUR_OF_DAY;

	/**
	 *
	 * 	分钟
	 * 	可以通过DateTime.now().get(DateTime.MINUTE_FIELD)来获取当前时间的分钟
	 *
	 */

	public static final int MINUTE_FIELD = Calendar.MINUTE;

	/**
	 *
	 * 	秒
	 * 	可以通过DateTime.now().get(DateTime.SECOND_FIELD)来获取当前时间的秒
	 *
	 */

	public static final int SECOND_FIELD = Calendar.SECOND;

	/**
	 *
	 * 	毫秒
	 *	 可以通过DateTime.now().get(DateTime.MILLISECOND_FIELD)来获取当前时间的毫秒
	 *
	 */

	public static final int MILLISECOND_FIELD = Calendar.MILLISECOND;

	private Calendar c; //日历类

	/**
	 *
	 * 	获取一个DateTime,此DateTime尚未初始化,表示的时间是1970-1-1 00:00:00.000
	 * 	要获取当前系统时间,请用DateTime.now();
	 *
	 */

	public DateTime() {

		c = Calendar.getInstance();

		c.clear();

	}

	/**
	 *
	 * 	设置时间
	 * <p>
	 *	 可以传入一个时间对象，将会被转换为DateTime类型
	 * </p>
	 *
	 *
	 *
	 * @param date 时间对象
	 *
	 */

	public DateTime(Date date) {

		c = Calendar.getInstance();

		c.setTime(date);

	}

	/**
	 *
	 * 	设置时间
	 * <p>
	 * 	可以传入一个日历对象，将会被转换为DateTime类型
	 * </p>
	 *
	 *
	 *
	 * @param calendar 日历对象
	 *
	 */

	public DateTime(Calendar calendar) {

		this.c = calendar;

	}

	/**
	 *
	 * 	获取当前系统时间
	 *
	 *
	 *
	 * @return DateTime 当前系统时间
	 *
	 */

	public static DateTime now() {

		Calendar calendar = Calendar.getInstance();

		return new DateTime(calendar);

	}

	/**
	 *
	 * 	用毫秒来设置时间, 时间的基数是1970-1-1 00:00:00.000;
	 * <p>
	 * 	比如,new DateTime(1000)
	 *
	 * 	则表示1970-1-1 00:00:01.000;<br>
	 * 	用负数表示基础时间以前的时间
	 * </p>
	 *
	 *
	 *
	 * @param milliseconds 毫秒
	 *
	 */

	public DateTime(long milliseconds) {

		c = Calendar.getInstance();

		c.setTimeInMillis(milliseconds);

	}

    public static int differentMonths(Calendar start, Calendar end) {
		int result = 0;

		int yearStart = start.get(Calendar.YEAR);
		int yearEnd = end.get(Calendar.YEAR);

		int monthStart = start.get(Calendar.MONTH) + 1;
		int monthEnd = end.get(Calendar.MONTH) + 1;

		if(yearEnd - yearStart == 0){
			result = monthEnd - monthStart;
		}else{
			result = (12 - monthStart) + monthEnd + (yearEnd - yearStart -1) * 12;
		}

		return result;
	}

	/**
	 * @Description: TODO (这里用一句话描述这个类的作用)
	 * @author tian
	 * @date 2022年10月17日 下午5:36:08
	 * @param startdate
	 * @param enddate
	 * @return
	 * @throws ParseException
	 */
	public static List<JSONObject> getStatisticsListDate(String startdate, String enddate) throws ParseException {
		Date now = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		if(StringUtils.isEmpty(startdate)) {
			startdate = "2018-01-01 00:00:00";
		}
		if(StringUtils.isEmpty(enddate)) {
			enddate = sf.format(now);
		}
		Date start = sf.parse(startdate);
		Date end = sf.parse(enddate);
		List<JSONObject> list = new ArrayList<JSONObject>();
		Calendar c = Calendar.getInstance();
		while(start.before(end)) {
			c.setTime(start);
			JSONObject js = new JSONObject();
			js.put("startdate", sf.format(start));
			c.add(Calendar.MONTH, 1);
			if(c.getTime().after(end)) {
				js.put("enddate", sf.format(end));
				list.add(js);
				break;
			}else {
				start = c.getTime();
				js.put("enddate", sf.format(start));
				list.add(js);
			}
		}
		return list;
	}

    /**
	 *
	 * 	转换为Date类型
	 *
	 *
	 *
	 * @return Date时间
	 *
	 */

	public Date toDate() {

		return c.getTime();

	}

	/**
	 *
	 *	转换成 日历对象
	 *
	 *
	 *
	 * @return Calendar对象
	 *
	 */

	public Calendar toCalendar() {

		return c;

	}

	/**
	 *
	 * 	转换成java.sql.Date(yyyy-MM-dd)日期
	 *
	 *
	 *
	 * @return java.sql.Date日期
	 *
	 */

	public java.sql.Date toSqlDate() {

		return new java.sql.Date(c.getTimeInMillis());

	}

	/**
	 *
	 * 	转换为java.sql.Time(hh:mm:ss)时间
	 *
	 *
	 *
	 * @return java.sql.Time时间
	 *
	 */

	public java.sql.Time toSqlTime() {

		return new java.sql.Time(c.getTimeInMillis());

	}

	/**
	 *
	 *	 转换为java.sql.Timestamp(时间戳)
	 *
	 *
	 *
	 * @return java.sql.Timestamp时间戳
	 *
	 */

	public Timestamp toSqlTimestamp() {

		return new Timestamp(c.getTimeInMillis());

	}

	/**
	 *
	 * 	解析时间
	 * <p>
	 *	 根据DateTime中的DEFAULT_TIME_FORMAT_PATTERN规则转换为hh:mm:ss或hh:mm格式
	 * </p>
	 *
	 *
	 *
	 * @param time 字符串格式时间
	 *
	 * @return DateTime 日期时间对象
	 *
	 */

	public static DateTime parseTime(String time) throws ParseException {

		try {

			return DateTime.parseDateTime(time, DateTime.DEFAULT_TIME_FORMAT_PATTERN);

		}
		catch ( ParseException e ) {

			return DateTime.parseDateTime(time, DateTime.DEFAULT_TIME_HHmm_FORMAT_PATTERN);

		}

	}

	/**
	 *
	 * 	解析日期
	 * <p>
	 * 	根据DateTime中的DEFAULT_DATE_FORMAT_PATTERN规则转换为yyyy-MM-dd格式
	 * </p>
	 *
	 *
	 *
	 * @param date 字符串格式日期
	 *
	 * @return DateTime 日期时间类
	 *
	 */

	public static DateTime parseDate(String date) throws ParseException {

		return DateTime.parseDateTime(date, DateTime.DEFAULT_DATE_FORMAT_PATTERN);

	}

	/**
	 *
	 * 	解析日期时间
	 * <p>
	 * 	根据DateTime中的DEFAULT_DATE_TIME_FORMAT_PATTERN规则转换为yyyy-MM-dd HH:mm:ss格式
	 * </p>
	 *
	 *
	 *
	 * @param datetime 字符串格式日期时间
	 *
	 * @return DateTime 日期时间对象
	 *
	 */

	public static DateTime parseDateTime(String datetime) throws ParseException {

		DateTime result = null;

		//尝试按yyyy-MM-dd HH:mm:ss分析

		try {

			result = DateTime.parseDateTime(datetime, DateTime.DEFAULT_DATE_TIME_FORMAT_PATTERN);

		}
		catch ( ParseException e ) {

			//解析错误

			result = null;

		}

		//尝试按yyyy-MM-dd HH:mm分析

		if (null == result) {

			try {

				result = DateTime.parseDateTime(datetime, DateTime.DEFAULT_DATE_TIME_HHmm_FORMAT_PATTERN);

			}
			catch ( ParseException e ) {

				//解析错误

				result = null;

			}

		}

		//尝试按yyyy-MM-dd HH分析

		if (null == result) {

			try {

				result = DateTime.parseDateTime(datetime, DateTime.DEFAULT_DATE_TIME_HH_FORMAT_PATTERN);

			}
			catch ( ParseException e ) {

				//解析错误

				result = null;

			}

		}

		//尝试按yyyy-MM-dd分析

		if (null == result) {

			try {

				result = DateTime.parseDate(datetime);

			}
			catch ( ParseException e ) {

				//解析错误

				result = null;

			}

		}

		//尝试按时间分析

		if (null == result) {

			result = DateTime.parseTime(datetime);

		}

		return result;

	}

	/**
	 *
	 * 	用指定的pattern分析字符串
	 * <p>
	 * pattern的用法参见java.text.SimpleDateFormat
	 * </p>
	 *
	 *
	 *
	 * @param datetime 字符串格式日期时间
	 *
	 * @param pattern 日期解析规则
	 *
	 * @return DateTime 日期时间对象
	 *
	 * @see SimpleDateFormat
	 *
	 */

	public static DateTime parseDateTime(String datetime, String pattern) throws ParseException {

		SimpleDateFormat fmt = (SimpleDateFormat) DateFormat.getDateInstance();

		fmt.applyPattern(pattern);

		return new DateTime(fmt.parse(datetime));

	}

	/**
	 *
	 * 	转换为 DEFAULT_DATE_FORMAT_PATTERN (yyyy-MM-dd) 格式字符串
	 *
	 *
	 *
	 * @return yyyy-MM-dd格式字符串
	 *
	 */

	public String toDateString() {

		return toDateTimeString(DateTime.DEFAULT_DATE_FORMAT_PATTERN);

	}

	/**
	 *
	 *	 转换为 DEFAULT_TIME_FORMAT_PATTERN (HH:mm:ss) 格式字符串
	 *
	 *
	 *
	 * @return HH:mm:ss 格式字符串
	 *
	 */

	public String toTimeString() {

		return toDateTimeString(DateTime.DEFAULT_TIME_FORMAT_PATTERN);

	}

	/**
	 *
	 *	 转换为 DEFAULT_DATE_TIME_FORMAT_PATTERN (yyyy-MM-dd HH:mm:ss) 格式字符串
	 *
	 *
	 *
	 * @return yyyy-MM-dd HH:mm:ss 格式字符串
	 *
	 */

	public String toDateTimeString() {

		return toDateTimeString(DateTime.DEFAULT_DATE_TIME_FORMAT_PATTERN);

	}

	/**
	 *
	 *	 使用日期转换pattern
	 * <p>
	 * pattern的用法参见java.text.SimpleDateFormat
	 * </p>
	 *
	 *
	 *
	 * @param pattern 日期解析规则
	 *
	 * @return 按规则转换后的日期时间字符串
	 *
	 */

	public String toDateTimeString(String pattern) {

		SimpleDateFormat fmt = (SimpleDateFormat) DateFormat.getDateInstance();

		fmt.applyPattern(pattern);

		return fmt.format(c.getTime());

	}

	/**
	 *
	 * 	获取DateTime所表示时间的某个度量的值
	 *
	 *
	 *
	 * @param field int 取值为:<br>
	 *            DateTime.YEAR_FIELD -- 返回年份<br>
	 *
	 *            DateTime.MONTH_FIELD -- 返回月份,一月份返回1,二月份返回2,依次类推<br>
	 *            DateTime.DAY_FIELD --
	 *
	 *            返回当前的天(本月中的)<br>
	 *            DateTime.HOUR_FIELD -- 返回小时数(本天中的),24小时制<br>
	 *
	 *            DateTime.MINUTE_FIELD -- 返回分钟数(本小时中的)<br>
	 *            DateTime.SECOND_FIELD --
	 *
	 *            返回秒数(本分钟中的)<br>
	 *            DateTime.MILLISECOND_FIELD -- 返回毫秒数(本秒中的)
	 *
	 * @return int field对应的值
	 *
	 */

	public int get(int field) {

		//月份需要+1(月份从0开始)

		if (DateTime.MONTH_FIELD == field) {

			return c.get(field) + 1;

		} else {

			return c.get(field);

		}

	}

	/**
	 *
	 * 返回自 1970-1-1 0:0:0 至此时间的毫秒数
	 *
	 *
	 *
	 * @return long 毫秒数
	 *
	 */

	public long getTimeInMillis() {

		return c.getTimeInMillis();

	}

	/**
	 *
	 * 设置field字段的值
	 *
	 *
	 *
	 * @param field int 取值为:<br>
	 *            DateTime.YEAR_FIELD -- 年份<br>
	 *
	 *            DateTime.MONTH_FIELD -- 月份,一月份从1开始<br>
	 *            DateTime.DAY_FIELD --
	 *
	 *            当前的天(本月中的)<br>
	 *            DateTime.HOUR_FIELD -- 小时数(本天中的),24小时制<br>
	 *
	 *            DateTime.MINUTE_FIELD -- 分钟数(本小时中的)<br>
	 *            DateTime.SECOND_FIELD --
	 *
	 *            秒数(本分钟中的)<br>
	 *            DateTime.MILLISECOND_FIELD -- 毫秒数(本秒中的)
	 *
	 * @param value
	 *
	 */

	public void set(int field, int value) {

		//月份需要-1(月份从0开始)

		if (DateTime.MONTH_FIELD == field) {

			c.set(field, value - 1);

		} else {

			c.set(field, value);

		}

	}

	/**
	 *
	 * 设置DateTime日期的年/月/日
	 *
	 *
	 *
	 * @param year 年
	 *
	 * @param month 月
	 *
	 * @param day 日
	 *
	 */

	public void set(int year, int month, int day) {

		set(DateTime.YEAR_FIELD, year);

		set(DateTime.MONTH_FIELD, month);

		set(DateTime.DAY_FIELD, day);

	}

	/**
	 *
	 * 设置DateTime日期的年/月/日/小时
	 *
	 *
	 *
	 * @param year 年
	 *
	 * @param month 月
	 *
	 * @param day 日
	 *
	 * @param hour 小时
	 *
	 */

	public void set(int year, int month, int day, int hour) {

		set(year, month, day);

		set(DateTime.HOUR_FIELD, hour);

	}

	/**
	 *
	 * 设置DateTime日期的年/月/日/小时/分钟
	 *
	 *
	 *
	 * @param year 年
	 *
	 * @param month 月
	 *
	 * @param day 日
	 *
	 * @param hour 小时
	 *
	 * @param minute 分钟
	 *
	 */

	public void set(int year, int month, int day, int hour, int minute) {

		set(year, month, day, hour);

		set(DateTime.MINUTE_FIELD, minute);

	}

	/**
	 *
	 * 设置DateTime日期的年/月/日/小时/分钟/秒
	 *
	 *
	 *
	 * @param year 年
	 *
	 * @param month 月
	 *
	 * @param day 日
	 *
	 * @param hour 小时
	 *
	 * @param minute 分钟
	 *
	 * @param second 秒
	 *
	 */

	public void set(int year, int month, int day, int hour, int minute, int second) {

		set(year, month, day, hour, minute);

		set(DateTime.SECOND_FIELD, second);

	}

	/**
	 *
	 * 设置DateTime日期的年/月/日/小时/分钟/秒/毫秒
	 *
	 *
	 *
	 * @param year 年
	 *
	 * @param month 月
	 *
	 * @param day 日
	 *
	 * @param hour 小时
	 *
	 * @param minute 分钟
	 *
	 * @param second 秒
	 *
	 * @param milliSecond 毫秒
	 *
	 */

	public void set(int year, int month, int day, int hour, int minute, int second, int milliSecond) {

		set(year, month, day, hour, minute, second);

		set(DateTime.MILLISECOND_FIELD, milliSecond);

	}

	/**
	 *
	 * 对field值进行相加
	 * <p>
	 * add() 的功能非常强大，add 可以对 DateTime 的字段进行计算。<br>
	 *
	 * 如果需要减去值，那么使用负数值就可以了，如 add(field, -value)。<br>
	 *
	 * 或者调用DateTime.reduce(int,int)进行日期相减
	 * </p>
	 *
	 *
	 *
	 * @param field int 取值为:<br>
	 *            DateTime.YEAR_FIELD -- 年份<br>
	 *
	 *            DateTime.MONTH_FIELD -- 月份,一月份从1开始<br>
	 *
	 *            DateTime.DAY_FIELD -- 当前的天(本月中的)<br>
	 *
	 *            DateTime.HOUR_FIELD -- 小时数(本天中的),24小时制<br>
	 *
	 *            DateTime.MINUTE_FIELD -- 分钟数(本小时中的)<br>
	 *
	 *            DateTime.SECOND_FIELD -- 秒数(本分钟中的)<br>
	 *
	 *            DateTime.MILLISECOND_FIELD -- 毫秒数(本秒中的)
	 *
	 * @param amount 数量(如果数量小于0则为相减)
	 *
	 */

	public void add(int field, int amount) {

		c.add(field, amount);

	}

	/**
	 *
	 * 对field值进行相减
	 * <p>
	 * 对add() 的功能进行封装，add 可以对 Calendar 的字段进行计算。<br>
	 *
	 * 如果需要减去值，那么使用负数值就可以了，如 add(field, -value)。<br>
	 *
	 * 详细用法参见Calendar.add(int,int)
	 * </p>
	 *
	 *
	 *
	 * @param field int 取值为:<br>
	 *            DateTime.YEAR_FIELD -- 年份<br>
	 *
	 *            DateTime.MONTH_FIELD -- 月份,一月份从1开始<br>
	 *
	 *            DateTime.DAY_FIELD -- 当前的天(本月中的)<br>
	 *
	 *            DateTime.HOUR_FIELD -- 小时数(本天中的),24小时制<br>
	 *
	 *            DateTime.MINUTE_FIELD -- 分钟数(本小时中的)<br>
	 *
	 *            DateTime.SECOND_FIELD -- 秒数(本分钟中的)<br>
	 *
	 *            DateTime.MILLISECOND_FIELD -- 毫秒数(本秒中的)
	 *
	 * @param amount 数量(如果数量小于0则为相加)
	 *
	 */

	public void reduce(int field, int amount) {

		c.add(field, -amount);

	}

	/**
	 *
	 * 判断此 DateTime 表示的时间是否在指定 Object 表示的时间之后，返回判断结果。
	 * <p>
	 * 此方法等效于：compareTo(when)
	 *
	 * > 0<br>
	 * 当且仅当 when 是一个 DateTime 实例时才返回 true。否则该方法返回 false。
	 *
	 *
	 *
	 * @param when 要比较的 Object
	 *
	 * @return 如果此 DateTime 的时间在 when 表示的时间之后，则返回 true；否则返回 false。
	 *
	 */

	public boolean after(Object when) {

		if (when instanceof DateTime) {

		return c.after(((DateTime) when).c);

		}

		return c.after(when);

	}

	/**
	 *
	 * 判断此 DateTime 表示的时间是否在指定 Object 表示的时间之前，返回判断结果。
	 * <p>
	 * 此方法等效于：compareTo(when)
	 *
	 * < 0<br>
	 * 当且仅当 when 是一个 DateTime 实例时才返回 true。否则该方法返回 false。
	 * </p>
	 *
	 *
	 *
	 * @param when 要比较的 Object
	 *
	 * @return 如果此 Calendar 的时间在 when 表示的时间之前，则返回 true；否则返回 false。
	 *
	 */

	public boolean before(Object when) {

		if (when instanceof DateTime) {

		return c.before(((DateTime) when).c);

		}

		return c.before(when);

	}

	/**
	 *
	 * 创建并返回此对象的一个副本
	 *
	 *
	 *
	 * @return 日期时间对象
	 *
	 */

	@Override

	public Object clone() {

		return new DateTime((Calendar) c.clone());

	}

	/**
	 *
	 * 返回该此日历的哈希码
	 *
	 *
	 *
	 * @return 此对象的哈希码值。
	 *
	 * @see Object
	 *
	 */

	@Override

	public int hashCode() {

		return c.hashCode();

	}

	/**

     * 将此 DateTime 与指定 Object 比较。

     *

     * @param obj - 要与之比较的对象。

     * @return 如果此对象等于 obj，则返回 true；否则返回 false。

     * @see Object

     */

    @Override
    public boolean equals(Object obj) {

        if(obj instanceof DateTime) {

            return c.equals(((DateTime) obj).toCalendar());

        }

        if(obj instanceof Calendar) {

            return c.equals(obj);

        }

        if(obj instanceof Date) {

            return c.getTime().equals(obj);

        }

        return false;

    }

    /**
     * @description 获取秒数 从1970-01-01 0:00:00.000开始
     * @param localDateTime
     * @throws ParseException
     * @return long    返回类型
     * @author   abner_ljx
     * @version  V1.0
     * @date	 2018年11月5日
     * @email	liujx@redoornetwork.com
     */
    public static long getTime(LocalDateTime localDateTime) throws ParseException {
    	long endDateTimeSSS = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
		return endDateTimeSSS/(60*1000);

    }

	/**
	 * 获取年-月-日的时间戳（秒级）
	 * @return
	 * @throws ParseException
	 */
	public static long getLongTime(String s){
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		long lt = 0;
		try {
			lt = df.parse(s).getTime()/1000;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return lt;
	}



	/**
	 * cal2比cal1多的天数 + 1,例如2019-06-01到2019-06-02算2天
	 * @param cal1
	 * @param cal2
	 * @return
	 */
	public static int differentDays(Calendar cal1, Calendar cal2)
	{
		int day1= cal1.get(Calendar.DAY_OF_YEAR);
		int day2 = cal2.get(Calendar.DAY_OF_YEAR);

		int year1 = cal1.get(Calendar.YEAR);
		int year2 = cal2.get(Calendar.YEAR);

		if(year1 != year2)   //不同一年
		{
			int timeDistance = 0 ;
			for(int i = year1 ; i < year2 ; i ++)
			{
				if(i%4==0 && i%100!=0 || i%400==0)    //闰年
				{
					timeDistance += 366;
				}
				else    //不是闰年
				{
					timeDistance += 365;
				}
			}
			return timeDistance + (day2 - day1 + 1) ;
		}
		else    //同年
		{
//			log.info("判断day2 - day1 : " + (day2-day1+1));
			return day2 - day1 + 1;
		}
	}

	/**
	 * date2比date1多的天数 例如2019-06-01到2019-06-02算2天
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int differentDays(Date date1, Date date2)
	{
		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(date1);

		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(date2);
		int day1= cal1.get(Calendar.DAY_OF_YEAR);
		int day2 = cal2.get(Calendar.DAY_OF_YEAR);

		int year1 = cal1.get(Calendar.YEAR);
		int year2 = cal2.get(Calendar.YEAR);
		if(year1 != year2)   //不同一年
		{
			int timeDistance = 0 ;
			for(int i = year1 ; i < year2 ; i ++)
			{
				if(i%4==0 && i%100!=0 || i%400==0)    //闰年
				{
					timeDistance += 366;
				}
				else    //不是闰年
				{
					timeDistance += 365;
				}
			}

			return timeDistance + (day2-day1) + 1;
		}
		else    //同年
		{
//			System.out.println("判断day2 - day1 : " + (day2-day1));
			return day2-day1 + 1;
		}
	}

	public static void main(String[] args) throws ParseException {
		/*DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
		Calendar start = Calendar.getInstance();
		start.setTime(format1.parse("2018-12-02"));
		Calendar end = Calendar.getInstance();
		end.setTime(format1.parse("2019-05-01"));
		System.out.println(differentDays(start,end));
		String[][] arr = getMonthDaysBetweenDate(format1.parse("2018-12-02"), format1.parse("2019-05-01"));
		for(String[] a: arr) {
			System.err.println(a[0]+"   "+a[1]);
		}*/
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		Date d1 = sf.parse("2023-08-09");
		Date d2 = sf.parse("2022-03-10");
		System.out.println(getMonthDiff(d1, d2));
/*		int months = DateTime.differentMonths(start, end);
		for (int i = 0; i <= months; i++) {
			int days = DateTime.daysToMonthEnd(start);
			if (i == months) {
				days = DateTime.differentDays(start, end);
				int year = end.get(Calendar.YEAR);
				int month = end.get(Calendar.MONTH) + 1;
				int day = end.get(Calendar.DAY_OF_MONTH);

				int year2 = start.get(Calendar.YEAR);
				int month2 = start.get(Calendar.MONTH) + 1;
				int day2 = start.get(Calendar.DAY_OF_MONTH);

				System.out.println(year2 + "年" + month2 + "月"+ day2 +"日到"+year + "年" + month + "月"+ day+"还有" + days + "天");
			}else{
				int year2 = start.get(Calendar.YEAR);
				int month2 = start.get(Calendar.MONTH) + 1;
				int day2 = start.get(Calendar.DAY_OF_MONTH);

				System.out.println(year2 + "年" + month2 + "月"+ day2 +"日到月底还有" + days + "天");
			}
			start.add(Calendar.DAY_OF_YEAR,days);
		}*/
	}

	/**
	 * 2019年3月11日到月底 21天
	 * @param cale
	 * @return
	 */
	public static int daysToMonthEnd(Calendar cale ){

		Calendar copy = Calendar.getInstance();
		copy.setTime(cale.getTime());
		int day = copy.get(Calendar.DAY_OF_MONTH);

		Calendar c = Calendar.getInstance();
		copy.add(Calendar.MONTH,1);
		int year = copy.get(Calendar.YEAR);
		int month = copy.get(Calendar.MONTH);

		c.set(year, month, 0);
		int dayOfMonth = c.get(Calendar.DAY_OF_MONTH);

		int daysToMonthEnd = dayOfMonth - day + 1;
		return daysToMonthEnd;

	}

	/**
	 * 时间段中各月份占用天数
	 * @param d1
	 * @param d2
	 * @return
	 */
	public static String[][] getMonthDaysBetweenDate(Date d1, Date d2){
		Calendar start = Calendar.getInstance();
		start.setTime(d1);
		Calendar end = Calendar.getInstance();
		end.setTime(d2);
		int months = DateTime.differentMonths(start, end);
		String[][] result = new String[months+1][2];
		for (int i = 0; i <= months; i++) {
			int days = DateTime.daysToMonthEnd(start);
			if (i == months) {
				days = DateTime.differentDays(start, end);
				int year2 = start.get(Calendar.YEAR);
				int month2 = start.get(Calendar.MONTH) + 1;
				String m = month2<10?"0"+month2: String.valueOf(month2);
				result[i][0] = year2+""+m;
				result[i][1] = String.valueOf(days);
			}else{
				int year2 = start.get(Calendar.YEAR);
				int month2 = start.get(Calendar.MONTH) + 1;
				String m = month2<10?"0"+month2: String.valueOf(month2);
				result[i][0] = year2+""+m;
				result[i][1] = String.valueOf(days);
			}
			start.add(Calendar.DAY_OF_YEAR,days);
		}
		return result;
	}

	/**
	* @Description: 获取统计数据范围时间
	* @author tian
	* @date 2022年7月22日 上午10:13:07
	* @param scope
	* @return
	 * @throws JSONException
	*/
	public static JSONObject getStatisticsDate(int scope) {
		JSONObject obj = new JSONObject();
		Calendar c = Calendar.getInstance();
		Date now = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		c.setTime(now);
		String enddate = sf.format(now) + " 23:59:59";
		String startdate = "";
		switch (scope) {
			case 1:{//一天
				c.add(Calendar.DAY_OF_YEAR, -1);
				startdate = sf.format(c.getTime()) + " 00:00:00";
			}
			break;
			case 2:{//一周
				c.add(Calendar.DAY_OF_YEAR, -7);
				startdate = sf.format(c.getTime())+ " 00:00:00";
			}
			break;
			case 3:{//一月
				c.add(Calendar.MONTH, -1);
				startdate = sf.format(c.getTime())+ " 00:00:00";
			}
			break;
			case 4:{//半年
				c.add(Calendar.MONTH, -6);
				startdate = sf.format(c.getTime())+ " 00:00:00";
			}
			break;
			case 5:{//一年
				c.add(Calendar.YEAR, -1);
				startdate = sf.format(c.getTime())+ " 00:00:00";
			}
			break;
			case 6:{//全部
				enddate = "";
			}
			break;
			default:
			break;
		}
		obj.put("startdate", startdate);
		obj.put("enddate", enddate);
		return obj;
	}

	/**
	 * @Description: 获取铁塔数据统计的账期
	 * @author tmy
	 * @date 2022年7月22日 上午10:13:07
	 * @param scope
	 * @return
	 */
	public static JSONObject getYearmonth(int scope) {
		JSONObject obj = new JSONObject();
		List<String> yearmonths = new ArrayList<>();
		Calendar c = Calendar.getInstance();
		Date now = new Date();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM");
		c.setTime(now);
		switch (scope) {
			case 1:{//一天
				c.add(Calendar.MONTH, -1);
				yearmonths.add(sf.format(c.getTime()));
			}
			break;
			case 2:{//一周
				c.add(Calendar.MONTH, -1);
				yearmonths.add(sf.format(c.getTime()));
			}
			break;
			case 3:{//一月
				c.add(Calendar.MONTH, -1);
				yearmonths.add(sf.format(c.getTime()));
			}
			break;
			case 4:{//半年
				for(int i=1;i<6;i++){
					c.add(Calendar.MONTH, -1);
					yearmonths.add(sf.format(c.getTime()));
				}
			}
			break;
			case 5:{//一年
				for(int i=1;i<12;i++){
					c.add(Calendar.MONTH, -1);
					yearmonths.add(sf.format(c.getTime()));
				}
			}
			break;
			case 6:{//全部
				c.add(Calendar.MONTH, -1);
				yearmonths.add(sf.format(c.getTime()));
			}
			break;
			default:
				break;
		}
		obj.put("staDates", yearmonths);
		return obj;
	}

	 public static int getMonthDiff(Date d1, Date d2) {
		 Calendar c1 = Calendar.getInstance();
		 Calendar c2 = Calendar.getInstance();
		 c1.setTime(d1);
		 c2.setTime(d2);
		 int year1 = c1.get(Calendar.YEAR);
		 int year2 = c2.get(Calendar.YEAR);
		 int month1 = c1.get(Calendar.MONTH);
		 int month2 = c2.get(Calendar.MONTH);
		 int day1 = c1.get(Calendar.DAY_OF_MONTH);
		 int day2 = c2.get(Calendar.DAY_OF_MONTH);
		 // 获取年的差值
		 int yearInterval = year1 - year2;
		 // 如果 d1的 月-日 小于 d2的 月-日 那么 yearInterval-- 这样就得到了相差的年数
		 if (month1 < month2 || month1 == month2 && day1 < day2) {
			 yearInterval--;
		 }
		 // 获取月数差值
		 int monthInterval = (month1 + 12) - month2;
		 if (day1 < day2) {
			 monthInterval--;
		 }
		 monthInterval %= 12;
		 int monthsDiff = Math.abs(yearInterval * 12 + monthInterval);
		 return monthsDiff;
	}
}
